using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Markup;
using Rhizome.Contract;
using Rhizome.Contract.Diag;
using Rhizome.Contract.Visitor;
using Rhizome.Model.Validation;

namespace Rhizome.Model
{
    [ContentProperty("Action")]
    public class CriterionAction<TPlant> : ActionBase<TPlant>, IValidate
    {
        private IAction _action;
        private ICriterion _criterion;

        public ICriterion Criterion
        {
            [DebuggerStepThrough]
            get { return _criterion; }
            set
            {
                if (_criterion == value) return;
                _criterion = value;
                var r = _criterion as RhizomeElement;
                if (r != null) r.Parent = this;
            }
        }

        /// <summary>
        ///   Inner action
        /// </summary>
        public IAction Action
        {
            [DebuggerStepThrough]
            get { return _action; }
            set
            {
                if (_action == value) return;
                _action = value;
                var r = _action as RhizomeElement;
                if (r != null) r.Parent = this;
            }
        }

        public override sealed void Process()
        {
			//if (Action == null) throw new ValidationException("Action not set");

            if (/*Criterion == null ||*/ Criterion.Test())
                Action.Process();
        }

    	#region Implementation of IValidate

    	public IEnumerable<IValidationResult> GetValidationResults()
    	{
			if (Action == null)
				yield return ValidationResult.ActionIsNull;

			if (Criterion == null)
				yield return ValidationResult.CriterionIsNull;
		}

    	#endregion

    	#region Overrides of RhizomeElement

    	protected override IEnumerable GetLocalElements()
    	{
    		yield return Criterion;
    		yield return Action;
    	}

    	#endregion
    }

    public sealed class CriterionAction : CriterionAction<object>
    {
    }
}